package pATT.bNEdit.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.TitledBorder;

import pATT.bNEdit.learning.AlgoritmoAprendizajeEstructural;
import pATT.bNEdit.learning.AlgoritmoK2;
import pATT.bNEdit.learning.AlgoritmoPC;


/**
 * <p>Title: BNEdit</p>
 * <p>Description: Bayesian Network Editor</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Martin Blech
 * @version 1.0
 */

public class StructuralLearningDialog extends JDialog
    implements ActionListener {
  /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
private static final String COMMAND_K2 = "COMMAND_K2";
  private static final String COMMAND_PC = "COMMAND_PC";

  public static final int CHOICE_OK = 0;
  public static final int CHOICE_CANCEL = 1;

  private static final int ALGORITHM_K2 = 0;
  private static final int ALGORITHM_PC = 1;

  String currDir = null;
  String fileName = null;
  int choice = CHOICE_CANCEL;
  int algorithmType = ALGORITHM_K2;
  AlgoritmoAprendizajeEstructural algorithm = null;

  JPanel panel1 = new JPanel();
  FlowLayout flowLayout1 = new FlowLayout();
  JPanel jPanelMain = new JPanel();
  TitledBorder titledBorder;
  JLabel labelParameterName = new JLabel();
  JSpinner spinnerParameterValue =
      new JSpinner(new SpinnerNumberModel(7, 0, 100, 1));
  JLabel labelLearningAlgorithm = new JLabel();
  JPanel jPanelParameter = new JPanel();
  JPanel jPanelAlgorithm = new JPanel();
  ButtonGroup buttonGroupAlgorithm = new ButtonGroup();
  JRadioButton chkK2 = new JRadioButton();
  JRadioButton chkPC = new JRadioButton();
  JPanel jPanelFile = new JPanel();
  JButton buttonSelectFile = new JButton();
  JButton buttonOk = new JButton();
  JButton buttonCancel = new JButton();
  JPanel jPanelOption = new JPanel();

  public StructuralLearningDialog(Frame frame, boolean modal) {
    super(frame, "Structural Learning", modal);
    try {
      jbInit();
      pack();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
  }

  public StructuralLearningDialog() {
    this(null, true);
  }

  private void jbInit() throws Exception {
    titledBorder = new TitledBorder("");
    panel1.setLayout(flowLayout1);
    panel1.setMinimumSize(new Dimension(300, 180));
    panel1.setOpaque(true);
    panel1.setPreferredSize(new Dimension(300, 180));
    jPanelMain.setBorder(titledBorder);
    jPanelMain.setMinimumSize(new Dimension(360, 150));
    jPanelMain.setPreferredSize(new Dimension(280, 150));
    titledBorder.setTitle("Parameters for Structural Learning");
    labelParameterName.setText("Parent limit:");
    labelLearningAlgorithm.setRequestFocusEnabled(true);
    labelLearningAlgorithm.setText("Learning Algorithm:");
    chkK2.setSelected(true);
    chkK2.setText("K2");
    chkK2.setActionCommand(COMMAND_K2);
    chkK2.addActionListener(this);
    chkPC.setText("PC");
    chkPC.setActionCommand(COMMAND_PC);
    chkPC.addActionListener(this);
    buttonSelectFile.setVerifyInputWhenFocusTarget(true);
    buttonSelectFile.setText("Select File");
    buttonSelectFile.addActionListener(new StructuralLearningDialog_buttonSelectFile_actionAdapter(this));
    buttonOk.setEnabled(false);
    buttonOk.setText("OK");
    buttonOk.addActionListener(new StructuralLearningDialog_buttonOk_actionAdapter(this));
    buttonCancel.setText("Cancel");
    buttonCancel.addActionListener(new StructuralLearningDialog_buttonCancel_actionAdapter(this));
    spinnerParameterValue.setPreferredSize(new Dimension(40, 20));
    this.setResizable(false);
    this.setTitle("");
    jPanelAlgorithm.add(labelLearningAlgorithm, null);
    jPanelAlgorithm.add(chkK2, null);
    jPanelAlgorithm.add(chkPC, null);
    jPanelMain.add(jPanelParameter, null);
    jPanelParameter.add(labelParameterName, null);
    jPanelParameter.add(spinnerParameterValue, null);
    this.getContentPane().add(panel1,  BorderLayout.CENTER);
    panel1.add(jPanelMain, null);
    jPanelMain.add(jPanelAlgorithm, null);
    buttonGroupAlgorithm.add(chkK2);
    buttonGroupAlgorithm.add(chkPC);
    jPanelMain.add(jPanelFile, null);
    jPanelFile.add(buttonSelectFile, null);
    jPanelMain.add(jPanelOption, null);
    jPanelOption.add(buttonOk, null);
    jPanelOption.add(buttonCancel, null);
  }

  /**
   * shows a dialog to choose a file as source for the structural learning
   * algorithm
   */
  public void chooseFile() {
    JFileChooser chooser;
    if (currDir==null)
      chooser = new JFileChooser();
    else
      chooser = new JFileChooser(currDir);
    chooser.setFileFilter(new DatFilter());
    int returnVal = chooser.showOpenDialog(this);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
      currDir = chooser.getCurrentDirectory().getPath();
      fileName = chooser.getSelectedFile().getPath();
      buttonOk.setEnabled(true);
    }
  }

  /**
   * actionPerformed
   *
   * @param e ActionEvent
   */
  public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals(COMMAND_K2)) {
      labelParameterName.setText("Parent limit:");
      spinnerParameterValue.setModel(new SpinnerNumberModel(7, 0, 100, 1));
    }
    else if (e.getActionCommand().equals(COMMAND_PC)) {
      labelParameterName.setText("Level of significance:");
      spinnerParameterValue.setModel(new SpinnerNumberModel(2, 0, 4, 1));
    }
  }

  /**
   * Filter for .dat files
   */
  private class DatFilter extends javax.swing.filechooser.FileFilter {
    public String getDescription() {
      return "*.dat";
    }

    public boolean accept(File f) {
      String name = f.getName();
      String ext = name.substring(name.lastIndexOf('.')+1).toLowerCase();
      return f.isDirectory() || ext.equals("dat");
    }
  }

  /**
   * Ok button's action event
   * @param e ActionEvent
   */
  void buttonOk_actionPerformed(ActionEvent e) {
    choice = CHOICE_OK;
    switch (algorithmType) {
      case ALGORITHM_K2:
        algorithm = new AlgoritmoK2(getParameter());
        break;
      case ALGORITHM_PC:
        algorithm = new AlgoritmoPC(getParameter());
        break;
    }
    this.hide();
  }

  /**
   * Gets the user's choice code
   * @return int - the user's choice code
   */
  public int getChoice() {
    return choice;
  }

  /**
   * Gets the user chosen file's name
   * @return String - complete path of the file
   */
  public String getFileName() {
    return fileName;
  }

  private int getParameter() {
    return ((Integer)spinnerParameterValue.getValue()).intValue();
  }

  /**
   * Get an instance of the user selected structural learning algorithm
   * @return AlgoritmoAprendizajeEstructural
   */
  public AlgoritmoAprendizajeEstructural getAlgorithm() {
    return algorithm;
  }

  /**
   * Cancel button's action event
   * @param e ActionEvent
   */
  void buttonCancel_actionPerformed(ActionEvent e) {
    choice = CHOICE_CANCEL;
    this.hide();
  }
}

class StructuralLearningDialog_buttonSelectFile_actionAdapter implements java.awt.event.ActionListener {
  StructuralLearningDialog adaptee;

  StructuralLearningDialog_buttonSelectFile_actionAdapter(StructuralLearningDialog adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.chooseFile();
  }
}

class StructuralLearningDialog_buttonOk_actionAdapter implements java.awt.event.ActionListener {
  StructuralLearningDialog adaptee;

  StructuralLearningDialog_buttonOk_actionAdapter(StructuralLearningDialog adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.buttonOk_actionPerformed(e);
  }
}

class StructuralLearningDialog_buttonCancel_actionAdapter implements java.awt.event.ActionListener {
  StructuralLearningDialog adaptee;

  StructuralLearningDialog_buttonCancel_actionAdapter(StructuralLearningDialog adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.buttonCancel_actionPerformed(e);
  }
}
